package com.auto.autoapp.step

import com.auto.autoapp.constants.Dy
import com.auto.autoapp.constants.DyLiveRoomId
import com.auto.autoapp.constants.SearchPageId
import com.auto.autoapp.constants.VideoPageId
import com.auto.autoapp.model.Direction
import com.auto.autoapp.model.SceneType
import com.auto.autoapp.model.StepType
import com.auto.autoapp.model.USerInfo
import com.auto.autoapp.model.VideoInfo
import com.auto.autoapp.util.CustomException
import com.auto.autoapp.util.SizeUtil
import com.auto.autoapp.util.StringUtil
import com.auto.autoapp.util.addLog
import com.auto.autoapp.util.appNotOpen
import com.auto.autoapp.util.clickFail
import com.auto.autoapp.util.clickOrTap
import com.auto.autoapp.util.getNodeById
import com.auto.autoapp.util.getNodeList
import com.auto.autoapp.util.jumpOp
import com.auto.autoapp.util.noComment
import com.auto.autoapp.util.nodeNotFind
import com.auto.autoapp.util.notLogin
import com.auto.autoapp.util.scrollFail
import com.auto.autoapp.util.setInputFail
import com.auto.autoapp.util.success
import com.ven.assists.AssistsCore
import com.ven.assists.AssistsCore.click
import com.ven.assists.AssistsCore.des
import com.ven.assists.AssistsCore.getBoundsInScreen
import com.ven.assists.AssistsCore.setNodeText
import com.ven.assists.stepper.Step
import kotlinx.coroutines.delay
import kotlin.random.Random

fun handleStep(step: Int?): Step {
    if (step == null || step == StepType.NONE.value) {
        return Step.none
    }
    if (step == StepType.REPEAT.value) {
        return Step.repeat
    }
    return Step.get(step)

}

/**
 * 判断组件是否全部可见
 */
fun allVisible(idList: MutableList<String>): Boolean {
    for (id in idList) {
        val node = AssistsCore.findById(id).firstOrNull()
        if (node == null || !node.isVisibleToUser) {
            return false
        }
    }
    return true
}

val pageIdMap = mutableMapOf<MutableList<String>, SceneType>(
    mutableListOf<String>(
        Dy.ID_DY_NICKNAME,
        Dy.ID_USER_LIKE_COUNT
    ) to SceneType.HOME_PAGE,

    mutableListOf<String>(
        Dy.ID_INDEX_BOTTOM_BAR,
        Dy.INDEX_TOP_TAB
    ) to SceneType.INDEX,
    mutableListOf<String>(
        DyLiveRoomId.CLOSE,
        DyLiveRoomId.AUDIENCE_NUM
    ) to SceneType.LIVE_ROOM,
    mutableListOf<String>(
        SearchPageId.SEARCH_INPUT,
        SearchPageId.SEARCH_BTN
    ) to SceneType.SEARCH_PAGE,
    mutableListOf<String>(
        VideoPageId.BACK,
    ) to SceneType.VIDEO_PAGE
)

/**
 * 获取当前页面
 */
fun getCurrentScene(): Result<SceneType> {
    for (entry in pageIdMap) {
        if (allVisible(entry.key)) return Result.success(entry.value)
    }
    return Result.success(SceneType.UNKNOWN)
}


/**
 * 前往抖音首页
 */
suspend fun toDyIndex(nextStep: Int? = 2): Step {
    addLog("前往抖音首页")
    if (AssistsCore.getPackageName() == Dy.PACKAGE_NAME) {
        val isIndex = getCurrentScene().getOrNull() == SceneType.INDEX

        if (!isIndex) {
            AssistsCore.back()
            addLog("当前不是首页，开始返回")
            return Step.repeat
        } else {
            addLog("已经切换至抖音首页")
            return Step.get(nextStep!!)
        }
    } else {
        val launchResult = AssistsCore.launchApp(Dy.PACKAGE_NAME)
        addLog("打开抖音：${if (launchResult) "成功" else "失败"}")
        delay(3000)
        return if (!launchResult) {
            addLog("尝试重新打开")
            Step.repeat
        } else {
            Step.repeat
        }
    }
}

/**
 * 发送评论
 */
//suspend fun sendComment(comment: String): Result<Any> {
//    val result = Dy.ID_COMMENT_NODE.clickOrTap()
//    if (result.isFailure) {
//        return Result.failure(CustomException(clickFail))
//    }
//    delay(500)
//    val node = Dy.ID_INPUT_COMMENT.getNodeById()
//    if (node.isFailure) {
//        addLog("评论输入框查找失败")
//        return Result.failure(CustomException(nodeNotFind))
//    }
//    node.getOrThrow().click()
//    delay(500)
//    node.getOrThrow().text = comment
//    addLog("输入内容成功")
//    return Result.success(success)
//
//}

/**
 * 上下滑屏
 */
suspend fun smoothScreen(
    direction: Direction? = Direction.T2B,
    nextStep: Int? = 2
): Step {
    val videoInfo = getVideoDetail()
//    randomOperate(videoInfo.getOrNull() ?: VideoInfo())
//    delay(200)
//    sendComment("123")
//    delay(1000)

//    Dy.ID_COMMENT_NODE.clickOrTap()
//
//    delay(500)
//    var node = Dy.ID_INPUT_COMMENT.getNodeById()
//    if (node.isFailure) {
//        addLog("评论输入框查找失败")
//    }else{
////        node.getOrThrow().click()
////        delay(1000)
////        node = Dy.ID_INPUT_COMMENT.getNodeById()
//        node.getOrThrow().setNodeText("hello")
//        delay(500)
//        addLog("输入内容成功")
//
//    }
//


    val rect = AssistsCore.getAppBoundsInScreen()
    if (rect == null) {
        addLog("滑动失败，无法获取当前页面信息")
        return Step.none
    }

    val centerX = rect.centerX().toFloat()
    val con1 = if (direction == Direction.T2B) rect.centerY() * 1.5f else rect.centerY() / 2.0f
    val con2 = if (direction == Direction.T2B) rect.centerY() / 2.0f else rect.centerY() * 1.5f

    val result =
        AssistsCore.gesture(floatArrayOf(centerX, con1), floatArrayOf(centerX, con2), 100, 300)
    if (result) {
        addLog("滑动成功")
        delay(1000)
        return handleStep(nextStep)
    }
    addLog("滑动失败")
    return Step.none
}

/**
 * 上下滑屏切换视频
 */
suspend fun exchangeVideo(direction: Direction? = Direction.T2B): Result<Any> {
    val rect = AssistsCore.getAppBoundsInScreen()
    if (rect == null) {
        addLog("滑动失败，无法获取当前页面信息")
        return Result.failure(CustomException(nodeNotFind))
    }

    val centerX = rect.centerX().toFloat()
    val con1 = if (direction == Direction.T2B) rect.centerY() * 1.5f else rect.centerY() / 2.0f
    val con2 = if (direction == Direction.T2B) rect.centerY() / 2.0f else rect.centerY() * 1.5f

    val result =
        AssistsCore.gesture(floatArrayOf(centerX, con1), floatArrayOf(centerX, con2), 100, 300)
    if (result) {
        addLog("滑动成功")
        delay(1000)
        return Result.success(success)
    }
    addLog("滑动失败")
    return Result.failure(CustomException(scrollFail))
}

/**
 * 随机点赞或者收藏
 */
suspend fun randomOperate(videoInfo: VideoInfo) {
    val likeRandom = Random.nextInt(1, 11)
    if (likeRandom >= 5 && videoInfo.liked != true) {
        val result = Dy.ID_VIDEO_LIKE.clickOrTap()
        if (result.isSuccess) {
            videoInfo.liked = true
            addLog("点击了喜欢")
            delay(200)
        }
    }

    val collectRandom = Random.nextInt(1, 11)
    if (collectRandom >= 5 && videoInfo.collected != true) {
        val result = Dy.ID_COLLECT_NODE.clickOrTap()
        if (result.isSuccess) {
            videoInfo.collected = true
            addLog("点击了收藏")
            delay(200)
        }
    }

}


/**
 * 获取视频相关信息
 * //昵称：com.ss.android.ugc.aweme:id/title
 *
 *     //点赞com.ss.android.ugc.aweme:id/f+f 描述：未点赞，喜欢6，按钮   已点赞，喜欢4792，按钮
 *     //未点赞，喜欢赞，按钮   未点赞，喜欢2.0万，按钮
 *     //
 *
 *     //评论：com.ss.android.ugc.aweme:id/ekd 描述：评论评论，按钮  评论98，按钮  评论1.4万，按钮
 *
 *     //收藏：com.ss.android.ugc.aweme:id/d-5 描述：未选中，收藏4，按钮  已选中，收藏527，按钮   未选中，收藏收藏，按钮
 *     //未选中，收藏8.5万，按钮
 *
 *     //转发com.ss.android.ugc.aweme:id/yro。分享5.9万，按钮
 *
 *     //标题描述：com.ss.android.ugc.aweme:id/desc
 *
 *     //用户头像：com.ss.android.ugc.aweme:id/user_avatar。 描述：电影浪浪山小妖怪
 */
fun getVideoDetail(): Result<VideoInfo> {
    val avatarNode = Dy.ID_USER_AVATAR.getNodeById()
    val likeNode = Dy.ID_VIDEO_LIKE.getNodeById()
    val commentNode = Dy.ID_COMMENT_NODE.getNodeById()
    val collectNode = Dy.ID_COLLECT_NODE.getNodeById()
    val shareNode = Dy.ID_SHARE_NODE.getNodeById()
    val titleNode = Dy.ID_VIDEO_USER_TITLE.getNodeById()
    val desNode = Dy.ID_VIDEO_DES.getNodeById()

    val videoInfo = VideoInfo()

    val des = avatarNode.getOrNull()?.des()
    videoInfo.userName = des
    val likeCount = likeNode.getOrNull()?.des()
    val likeArray = likeCount?.split("，") ?: listOf<String>()

    if (likeArray.size == 3) {
        videoInfo.liked = likeArray[0].contains("已")
        videoInfo.likeCount = StringUtil.parseCount(likeArray[1])
    }


    val commentCount = commentNode.getOrNull()?.des()
    val commentArray = commentCount?.split("，") ?: listOf<String>()
    if (commentArray.size == 2) {
        videoInfo.commentCount = StringUtil.parseCount(commentArray[1])
    }


    val collectCount = collectNode.getOrNull()?.des()
    val collectArray = collectCount?.split("，") ?: listOf<String>()
    if (collectArray.size == 3) {
        videoInfo.collected = collectArray[0].contains("已")
        videoInfo.collectCount = StringUtil.parseCount(collectArray[1])
    }

    val shareCount = shareNode.getOrNull()?.des()
    val shareArray = shareCount?.split("，") ?: listOf<String>()
    if (shareArray.size == 2) {
        videoInfo.shareCount = StringUtil.parseCount(shareArray[0])
    }

    val title = titleNode.getOrNull()?.text
    val desInfo = desNode.getOrNull()?.text
    videoInfo.videoDes = desInfo?.toString()

    addLog(
        videoInfo.toString()
    )
    return Result.success(videoInfo)

}

/**
 * 点击评论按钮
 */
suspend fun clickCommentBtn(): Result<Any> {
    var commentNode = Dy.ID_COMMENT_NODE.getNodeById()
    if (commentNode.isFailure) {
        addLog("无法找到评论按钮节点")
        return Result.failure(CustomException(nodeNotFind))
    }
    val clickResult = commentNode.getOrThrow().clickOrTap()
    if (clickResult.isSuccess) {
        addLog("点击评论按钮成功")
        return Result.success(success)
    }
    addLog("点击评论按钮失败")
    return Result.failure(CustomException(clickFail))
}

/**
 * 进入评论区列表
 */
//suspend fun toCommentList(): Result<Any>{
//
//}

/**
 * 是否为可进入直播间的视频
 */
fun isLiveVideo(): Result<Any> {
    val node = Dy.ID_IS_LIVE.getNodeById()
    if (node.isFailure) {
        return Result.failure(CustomException(nodeNotFind))
    }
    return Result.success(success)
}

//回复评论
suspend fun replyComment(comment: String): Result<Any> {
    var node = Dy.ID_REPLY_COMMENT.getNodeById()
    if (node.isFailure) {
        addLog("寻找回复按钮失败")
        return Result.failure(CustomException(nodeNotFind))
    } else {
        node.getOrThrow().click()
        delay(500)
        var node = Dy.ID_COMMENT_INPUT.getNodeById()
        delay(100)
        node.getOrThrow().setNodeText(comment)
        addLog("设置回复内容成功")
        var sendBtn = Dy.ID_COMMENT_REPLAY_SEND.getNodeById()
        if (sendBtn.isFailure) {
            addLog("获取回复按钮")
            return Result.failure(CustomException(nodeNotFind))
        }
        val clickResult = sendBtn.getOrThrow().clickOrTap()
        if (clickResult.isFailure) {
            addLog("点击回复按钮失败")
            return Result.failure(CustomException(clickFail))
        }
        delay(500)
    }
    return Result.success(success)
}

/**
 * 评论视频
 */
suspend fun sendComment(comment: String): Result<Any> {
    var node = Dy.ID_INPUT_COMMENT.getNodeById()
    if (node.isFailure) {
        addLog("评论输入框查找失败")
        return Result.failure(CustomException(nodeNotFind))
    } else {
        node.getOrThrow().click()
        delay(500)
        var node = Dy.ID_INPUT_COMMENT.getNodeById()
        delay(100)
        node.getOrThrow().setNodeText(comment)
        addLog("设置评论内容成功")
        var sendBtn = Dy.ID_SEND_COMMENT.getNodeById()
        if (sendBtn.isFailure) {
            addLog("获取发送按钮失败")
            return Result.failure(CustomException(nodeNotFind))
        }
        val clickResult = sendBtn.getOrThrow().clickOrTap()
        if (clickResult.isFailure) {
            addLog("点击发送按钮失败")
            return Result.failure(CustomException(clickFail))
        }
        delay(500)
    }
    return Result.success(success)
}

/**
 * 获取用户主页信息
 */
suspend fun getUserInfo(): Result<USerInfo> {
    val userInfo = USerInfo()
    val dyCode = Dy.ID_DY_CODE_TXT.getNodeById().getOrNull()?.text.toString()
    userInfo.dyCode = dyCode
    userInfo.nickName = Dy.ID_DY_NICKNAME.getNodeById().getOrNull()?.text.toString()
    userInfo.likeCount = Dy.ID_USER_LIKE_COUNT.getNodeById().getOrNull()?.text.toString()
    userInfo.fansCount = Dy.ID_USER_FAN_COUNT.getNodeById().getOrNull()?.text.toString()


    userInfo.likeCount = StringUtil.parseCount(userInfo.likeCount).toString()
    userInfo.fansCount = StringUtil.parseCount(userInfo.fansCount).toString()
    val videoStr = Dy.ID_VIDEO_COUNT.getNodeById(last = false).getOrNull()?.text.toString()
    userInfo.videoCount = Dy.ID_VIDEO_COUNT.getNodeById(last = false).getOrNull()?.text.toString()
    if (videoStr.startsWith("作品") && videoStr.split(" ").size > 1) {
        userInfo.videoCount = StringUtil.parseCount(videoStr.split(" ")[1]).toString()
    }

    val typeNode = Dy.ID_ACCOUNT_SPECIAL.getNodeById().getOrNull()
    if (typeNode != null && typeNode.childCount > 0) {
        userInfo.accountType = typeNode.getChild(0).text.toString()
        val moreOp = Dy.ID_USER_DETAIL_RIGHT_OP_MORE.getNodeById().getOrNull()
        val moreOpenSuccess = moreOp?.clickOrTap()?.isSuccess == true
        delay(1000)
        if (moreOpenSuccess) {
            userInfo.dyCode = Dy.ID_USER_DETAIL_DY_CODE.getNodeById().getOrNull()?.text?.toString()
            Dy.ID_USER_DETAIL_CLOSE.clickOrTap()
            delay(1000)
        }

    }


    val basicInfoNode = Dy.ID_USER_BASIC_INFO.getNodeById().getOrNull()
    val desList = mutableListOf<String>()
    if (basicInfoNode != null) {
        for (i in 0 until basicInfoNode.childCount) {
            val basicItemNode = basicInfoNode.getChild(i)
            val des = basicItemNode.des()
            desList.add(des)
            if (des.startsWith("IP：") && des.split("IP：").size > 1) {
                userInfo.ip = des.split("IP：")[1]
                continue
            }

            if (des.startsWith("男") or des.startsWith("女")) {
                userInfo.sex = des.substring(0, 1)
                if (des.contains("·") && des.split("·").size > 1) {
                    userInfo.age = des.split("·")[1].replace("岁", "")
                }
            }
        }
    }
    val ipIndex = desList.indexOfFirst {
        it.startsWith("IP：")
    }
    if (ipIndex >= 0 && ipIndex < desList.size - 2 &&
        (desList[ipIndex + 2].startsWith("男") or desList[ipIndex + 2].startsWith("女"))
    ) {
        userInfo.area = desList[ipIndex + 1]
    }

    return Result.success(userInfo)
}

/**
 * 关注用户
 */
suspend fun focusUser(): Result<Any> {
    val focusNode = Dy.ID_USER_FOCUS.getNodeById().getOrNull()
    if (focusNode == null) {
        return Result.failure(CustomException(nodeNotFind))
    }
    val hasLiked = focusNode.des().contains("已")
    if (hasLiked) {
        addLog("已关注")
        return Result.success(success)
    }
    addLog("点击关注")
    return focusNode.clickOrTap()
}


fun getDyCode(): Result<Any> {
    val nodeResult = Dy.ID_DY_CODE_TXT.getNodeById()
    if (nodeResult.isSuccess) {
        val node = nodeResult.getOrThrow()
        val codeInfo = node.text
        addLog("获取抖音号：$codeInfo")
        return Result.success(codeInfo)
    } else {
        addLog("获取抖音号失败，请检查用户是否已登陆")
        return Result.failure(CustomException(notLogin))
    }
}

/**
 * 点赞
 * [id]:组件id
 * [jumpLiked]：如果已点赞，是否跳过，防治点击之后取消点赞
 */
suspend fun clickLike(id: String = Dy.ID_VIDEO_LIKE, jumpLiked: Boolean = true): Result<Any> {
//    val likeNodeList = id.getNodeList().getOrNull()?:mutableListOf()
//    likeNodeList.forEach {
//        addLog("nodeInfo:${it.isVisibleToUser}--${it.des()}")
//
//    }


    // 避免误点取消点赞，先判断当前是否已点赞
    val likeNode = id.getNodeList().getOrNull()?.firstOrNull()
    if (likeNode == null) {
        addLog("点赞节点未找到")
        return Result.failure(CustomException(nodeNotFind))
    }
    addLog("点赞节点信息：${likeNode.des()}")
    val liked = likeNode.des().contains("已") == true
    if (!liked || !jumpLiked) {
        val result = likeNode.clickOrTap()
        addLog("执行点赞：${if (result.isSuccess) "成功" else "失败"}")
    } else {
        addLog("当前已点赞，跳过")
    }
    return Result.success(success)
}

/**
 * 发送评论
 */
suspend fun sendComment(commentList: MutableList<String>): Result<Any> {
    if (commentList.isEmpty()) {
        addLog("评论内容为空")
        return Result.failure(CustomException(noComment))
    }
    val comment = commentList.random()
    val isLive = isLiveVideo()
    if (isLive.isSuccess) {
        addLog("直播视频，跳过评论")
        return Result.failure(CustomException(jumpOp))
    }
    val click = clickCommentBtn()
    if (click.isSuccess) {
        delay(600)
        val sendResult = sendComment(comment)
        addLog("评论(${comment})：${if (sendResult.isSuccess) "成功" else "失败"}")
        AssistsCore.back()
        delay(600)
    } else {
        addLog("打开评论区失败，跳过评论")
        return Result.failure(CustomException(jumpOp))
    }
    return Result.success(success)

}


/**
 * 发送私信
 */
suspend fun sendPrivateMsg(msg: String): Result<Any> {
    val sendMsgNode = Dy.ID_USER_SEND_PRIVATE_MSG.getNodeById().getOrNull()
    if (sendMsgNode == null) {
        addLog("未找到私信按钮")
        return Result.failure(CustomException(nodeNotFind))
    }
    addLog("点击发私信")
    val clickResult = sendMsgNode.clickOrTap()
    if (clickResult.isFailure) {
        return clickResult
    }
    delay(1000)
    val inputNode = Dy.ID_PRIVATE_MSG_INPUT.getNodeById().getOrNull()
    if (inputNode == null) {
        addLog("未找到输入框，开始返回")
        AssistsCore.back()
        return Result.failure(CustomException(nodeNotFind))
    }
    addLog("是否可点击：${inputNode.isClickable}")
    val setResult = inputNode.setNodeText(msg)
    if (!setResult) {
        return Result.failure(CustomException(setInputFail))
    }
    val sendNode = Dy.ID_PRIVATE_MSG_SEND.getNodeById().getOrNull()
    if (sendNode == null) {
        AssistsCore.back()
        return Result.failure(CustomException(nodeNotFind))
    }
    return sendNode.clickOrTap()
}

/**
 * 切换搜索结果导航栏
 */
suspend fun changeSearchResultTab(tab: String): Result<Any> {
    val topNavBox = AssistsCore.findById(SearchPageId.SEARCH_TAB_SCROLL).firstOrNull()
    var navRect = topNavBox?.getBoundsInScreen()
    if (navRect == null) {
        addLog("首页tab导航栏获取失败")
        return Result.failure(CustomException(nodeNotFind))
    }

    var topBarNode =
        AssistsCore.findByTextAllMatch(tab, filterViewId = SearchPageId.TAB_TEXT)
            .firstOrNull()
    if (topBarNode == null) {
        addLog("导航栏查找\"${tab}\"失败")
        return Result.failure(CustomException(nodeNotFind))
    }
    var nodeRect = topBarNode.getBoundsInScreen()


    val innerResult = SizeUtil.horizontalOffsetToContain(nodeRect, navRect)
    if (!innerResult.first) {
        val offset = innerResult.second
        val startX = if (offset >= 0) navRect.left + 10f else navRect.right - 10f
        val startPosition = floatArrayOf(startX, navRect.centerY().toFloat())
        val endPosition = floatArrayOf(
            startX + offset, navRect.centerY().toFloat()
        )
        val scrollResult = AssistsCore.gesture(startPosition, endPosition, 0, 100)
        if (!scrollResult) {
            addLog("导航栏滑动失败")
            return Result.failure(CustomException(nodeNotFind))
        }
        addLog("滑动导航栏至$tab")
        delay(1000)
        topBarNode =
            AssistsCore.findByTextAllMatch(tab, filterViewId = Dy.INDEX_TOP_TAB_TEXT)
                .firstOrNull()
        if (topBarNode == null) {
            addLog("滑动后未找到：$tab")
            return Result.failure(CustomException(nodeNotFind))
        }

    }
    val result = topBarNode.clickOrTap()
    if (result.isSuccess) {
        addLog("切换至\"${tab}\"")
        return Result.success(success)
    } else {
        addLog("切换失败,请重新尝试")
        return Result.failure(CustomException(clickFail))
    }
}

suspend fun scroll(
    id: String,
    direction: Direction,
    from: Float = 0f,
    to: Float = 1.0f,
    delayTime: Long = 100,
    duration: Long = 500,
    offSet: Int = 20
): Result<Any> {
    val node = id.getNodeList().getOrNull()?.firstOrNull()
    node?.isScrollable
    if (node == null) {
        return Result.failure(CustomException(nodeNotFind))
    }
    val bounds = node.getBoundsInScreen()
    val isHor = (direction == Direction.L2R) or (direction == Direction.R2L)
    var startPosition: FloatArray
    var endPosition: FloatArray
    if (isHor) {
        val centerY = bounds.centerY().toFloat()
        if (direction == Direction.L2R) {
            startPosition = floatArrayOf((1 + from) * bounds.left + offSet, centerY)
            endPosition = floatArrayOf((1 - to) * bounds.right - offSet, centerY)
        } else {
            startPosition = floatArrayOf((1 - from) * bounds.right - offSet, centerY)
            endPosition = floatArrayOf((1 + to) * bounds.left + offSet, centerY)
        }
    } else {
        val centerX = bounds.centerX().toFloat()
        if (direction == Direction.T2B) {
            startPosition = floatArrayOf(centerX, (1 + from) * bounds.top + offSet)
            endPosition = floatArrayOf(centerX, (1 - to) * bounds.bottom - offSet)
        } else {
            startPosition = floatArrayOf(centerX, (1 - from) * bounds.bottom - offSet)
            endPosition = floatArrayOf(centerX, (1 + to) * bounds.top + offSet)
        }
    }
    val result = AssistsCore.gesture(startPosition, endPosition, delayTime, duration)
    if (!result) {
        return Result.failure(CustomException(scrollFail))
    }

    return Result.success(success)
}

/**
 * 检查是否登录
 */
suspend fun checkLogin(): Result<Any> {
    addLog("跳转首页成功，开始切换tab->我的")

    val result = Dy.ID_TAB_MINE.clickOrTap()
    if (result.isFailure) {
        addLog("切换至我的页面失败")
        return Result.failure(CustomException(clickFail))
    }
    delay(1500)
    val codeResult = getDyCode()
    if (codeResult.isFailure) {
        addLog("未获取到抖音号，请确认是否已登录")
        return Result.failure(CustomException(notLogin))
    }
    delay(1500)
    val indexTab = Dy.ID_TAB_MINE.getNodeById(last = false)
    if (indexTab.isFailure) {
        addLog("无法切换至首页，请检查页面")
        return Result.failure(CustomException(nodeNotFind))
    }

    val toIndexResult = indexTab.getOrNull()!!.clickOrTap()
    if (toIndexResult.isSuccess) {
        addLog("切换至首页成功")
    } else {
        addLog("切换至首页失败")
    }
    return codeResult
}

/**
 * 回退至搜索页面
 * 尝试十次
 */
suspend fun backToSearchPage(): Result<Any> {
    if (AssistsCore.getPackageName() != Dy.PACKAGE_NAME) {
        return Result.failure(CustomException(appNotOpen))
    }
    var retryCount = 0
    val maxRetryCount = 10
    while (true) {
        val searchInput = SearchPageId.SEARCH_INPUT.getNodeList().getOrNull()?.firstOrNull()
        retryCount++
        if (searchInput == null) {
            if (retryCount >= maxRetryCount) {
                return Result.failure(CustomException(nodeNotFind))
            }

            AssistsCore.back()
            delay(2000)
        } else {
            return Result.success(success)
        }

    }
}